package com.zhou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.zhou.entity.Billdetail;
import com.zhou.mapper.BilldetailMapper;
import com.zhou.mapper.BillsMapper;
import com.zhou.entity.Bills;
import com.zhou.vo.BillListResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.zhou.service.BillsService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务接口实现
 *
 * @author jilin
 * @since 2021-11-17 22:47:37
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class BillsServiceImpl implements BillsService {
    @Autowired
    BillsMapper billsMapper;
    @Autowired
    BilldetailMapper billdetailMapper;

    @Override
    public List<BillListResp> qryBillList() {
        List<Bills> billlist = billsMapper.qryBillList(null, null);
        if (CollectionUtils.isEmpty(billlist)) {
            return Lists.newArrayList();
        }
        //获取账本id
        Set<Integer> ids = billlist.stream().map(Bills::getId).collect(Collectors.toSet());
        //构建wrapper查询条件
        QueryWrapper<Billdetail> query = new QueryWrapper<>();
        query.in(!CollectionUtils.isEmpty(ids), "billid", ids);
        //根据billid查询对应的detail
        List<Billdetail> billdetaillist = billdetailMapper.selectList(query);
        if (billdetaillist.isEmpty()) {
            return Lists.newArrayList();
        }
        //将detail按billid分组
        Map<Integer, List<Billdetail>> detailMap = billdetaillist.stream().collect(Collectors.groupingBy(Billdetail::getBillid));
        Iterator<Bills> iterator = billlist.iterator();
        List<BillListResp> resp = Lists.newArrayList();
        while (iterator.hasNext()) {
            Bills next = iterator.next();
            Integer id = next.getId();
            List<Billdetail> detailList = detailMap.get(id);
            if (CollectionUtils.isEmpty(detailList)) {
                continue;
            }
            Optional<Billdetail> optional = detailList.stream().reduce((sum, d) -> {
                sum.setBudget(d.getBudget() + sum.getBudget());
                sum.setDifference(d.getDifference() + sum.getDifference());
                sum.setInvestment(d.getInvestment() + sum.getInvestment());
                return sum;
            });
            BillListResp billListResp = new BillListResp();
            Billdetail billdetail = optional.orElse(new Billdetail());
            billListResp.setDiffnum(billdetail.getDifference());
            billListResp.setDonenum(billdetail.getInvestment());
            billListResp.setPlannum(billdetail.getBudget());
            billListResp.setId(id);
            billListResp.setName(next.getBname());
            resp.add(billListResp);
        }
        return resp;
    }

    @Override
    public void createBill(String name) throws Exception{
        if (Strings.isBlank(name)) {
            throw new Exception("name cant be empty");
        }
        //检查数据库是否有该数据
        Bills bill = new Bills();
        List<Bills> bills = billsMapper.qryBillList(null, name);
        if (!CollectionUtils.isEmpty(bills)) {
            throw new Exception("数据库中已经有该数据");
        }
        //设置
        bill.setBname(name);
        bill.setCreatetime(new Date());
        bill.setUpdatetime(new Date());
        //插入数据库
        billsMapper.ceateBill(bill);
    }

    /**
     * 更新账单
     * @param name
     */
    @Transactional
    @Override
    public void updateBill(int id, String name) throws Exception {
        //如果查询不到对应账本，则创建账本
        List<Bills> bills = billsMapper.qryBillList(null, name);
        if (CollectionUtils.isEmpty(bills)) {
            createBill(name);
        }
        Bills bill = new Bills();
        bill.setId(id);
        bill.setBname(name);
        bill.setUpdatetime(new Date());
        billsMapper.updateBill(bill);
    }

    /**
     * 删除操作
     * @param id
     */
    @Transactional
    @Override
    public void deleteBill(int id) {
        Bills bill = new Bills();
        bill.setId(id);
        billsMapper.deleteBill(bill);
    }
}